package demo2;

import java.io.Serializable;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: DELL
 * Date: 2023-08-07
 * Time: 15:39
 */

class SingleLazy implements Serializable {

    /**
     * 当一个类实现了Serializable接口时，编译器会生成一个默认的序列化ID（serialization ID）
     * 这个ID用于在对象序列化和反序列化过程中进行版本控制，确保序列化和反序列化的兼容性
     * <p>
     * 设置serialVersionUID的目的是为了在类的定义发生修改后，可以在反序列化时判断是否与序列化时的版本一致。
     * 如果serialVersionUID一致，则认为两个版本是兼容的，可以进行反序列化；
     * 如果不一致，则会抛出InvalidClassException，阻止反序列化操作
     * <p>
     * TODO : 如果类的定义发生了不兼容的变化（如删除字段、修改字段类型等），
     *        手动指定serialVersionUID可以确保正确处理序列化和反序列化的兼容性
     */

    // 自定义的序列化 ID
    private static final long serialVersionUID = 1L;

    // 提供一个未负值的的变量
    private static volatile SingleLazy instance = null;

    // 提供一个私有的无参构造方法
    private SingleLazy() {

        // 构造方法中做出判断, 防止反射绕过私有方法调用构造方法创建实例
        if (instance != null) {
            throw new IllegalStateException("已经存在单例实例");
        }
    }

    // 提供 get 方法供外部获 instance 取使用
    public static SingleLazy getInstance() {

        if (instance == null) {
            synchronized (SingleLazy.class) {
                // 判断是否为第一次创建
                if (instance == null) {
                    instance = new SingleLazy();
                }
            }
        }

        // 首次使用则创建, 后续在此调用 getInstance 方法时直接返回
        return instance;
    }

    // 在反序列化时, 会调用该方法返回单例对象的实例 -- Java 中的特殊方法
    protected Object readResolve() {
        return getInstance();
    }

}

public class Thread4 {

    public static void main(String[] args) {
        SingleLazy singleLazy = SingleLazy.getInstance();
        SingleLazy singleLazy1 = SingleLazy.getInstance();

        System.out.println(singleLazy.equals(singleLazy1));
    }
}
